package be.kuleuven.cs.mop.app.controllers;


import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import be.kuleuven.cs.mop.app.System;
import be.kuleuven.cs.mop.domain.exceptions.InvalidCurrentUserException;
import be.kuleuven.cs.mop.domain.exceptions.TaskManagerException;
import be.kuleuven.cs.mop.domain.model.Reservation;
import be.kuleuven.cs.mop.domain.model.Resource;
import be.kuleuven.cs.mop.domain.model.ResourceType;
import be.kuleuven.cs.mop.domain.model.Task;
import be.kuleuven.cs.mop.domain.model.impl.ResourceImpl;
import be.kuleuven.cs.mop.domain.model.impl.ResourceTypeImpl;
import be.kuleuven.cs.mop.domain.model.impl.TaskImpl;



/**
 * The {@link Controller} responsible for handling {@link Resource} operations
 */
public class ResourceController extends Controller {
	
	/**
	 * Creates a new ResourceController
	 * @param system - The <code>System</code>
	 */
	public ResourceController(final System system) {
		super(system);
	}
	
	
	
	/**
	 * Creates a new {@link Resource}
	 * @param resourceType 	- The given {@link ResourceType}
	 * @param description 	- The given description
	 * 
	 * @throws	TaskManagerException RESOURCE_INVALID_DESCRIPTION - !{@link ResourceImpl#isValidDescription(String)}
	 * @throws 	TaskManagerExceptionor INVALID_RESOURCE_TYPE - !{@link ResourceImpl#isValidResourceType(ResourceTypeImpl)}
	 * @throws InvalidCurrentUserException NO_USER_LOGGED_IN - {@link #checkIfUserIsLoggedIn()}
	 */
	public Resource createResource(final ResourceType resourceType, final String description) throws TaskManagerException, InvalidCurrentUserException {
		checkIfUserIsLoggedIn();
		return new ResourceImpl(getWorld(), description, (ResourceTypeImpl)resourceType);
	}
	
	/**
	 * Returns a <code>List</code> of all existing {@link Resource}s
	 * @throws InvalidCurrentUserException NO_USER_LOGGED_IN - {@link #checkIfUserIsLoggedIn()}
	 */
	public List<Resource> getResources() throws InvalidCurrentUserException {
		checkIfUserIsLoggedIn();
		return new ArrayList<Resource>(getWorld().getResources());
	}
	
	/**
	 * Returns a <code>List</code> of all existing {@link ResourceType}s
	 * @throws InvalidCurrentUserException NO_USER_LOGGED_IN - {@link #checkIfUserIsLoggedIn()}
	 */
	public List<ResourceType> getResourceTypes() throws InvalidCurrentUserException {
		checkIfUserIsLoggedIn();
		return new ArrayList<ResourceType>(getWorld().getResourceTypes());
	}
	
	/**
	 * Returns a <code>List</code> of all existing {@link Reservations}s for{@link Resource}s
	 * @throws InvalidCurrentUserException NO_USER_LOGGED_IN - {@link #checkIfUserIsLoggedIn()}
	 */
	public List<Reservation> getReservations(Resource resource) throws InvalidCurrentUserException {
		checkIfUserIsLoggedIn();
		return new ArrayList<Reservation>(resource.getReservations());
	}
	
	/**
	 * Creates a new {@link Reservation}
	 * @param task 		- The {@link Task} making the <code>Reservation</code>
	 * @param resource 	- The {@link Resource} to be reserved
	 * @param date 		- The date for the <code>Reservation</code>
	 * @param duration 	- The duration of the <code>Reservation</code>, in milliseconds
	 * 
	 * @throws TaskManagerException 
	 * @throws InvalidCurrentUserException NO_USER_LOGGED_IN - {@link #checkIfUserIsLoggedIn()}
	 */
	public void makeResourceReservation(final Task task, final Resource resource,
			final Calendar date, final long duration) throws TaskManagerException, InvalidCurrentUserException {
		checkIfUserIsLoggedIn();
		((TaskImpl)task).makeResourceReservation((ResourceImpl)resource, date, duration);
	}
}